package com.leeson.portal.core.service.action;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

import org.apache.log4j.Logger;

import com.leeson.portal.core.model.Config;
import com.leeson.portal.core.service.utils.Authenticator;
import com.leeson.portal.core.service.utils.PortalUtil;

/**
 * Challenge_V2包
 * 
 * @author LeeSon QQ:25901875
 * 
 */
public class ReqInfo {

	private static Logger log = Logger.getLogger(ReqInfo.class);

	private static Config config = Config.getInstance();
	/**
	 * basIp AC通信IP地址 basPort AC socket端口号 sharedSecret BAS和Portal
	 * Server之间的共享密钥secret 相当于签名 authType 定义认证方式 有PAP/CHAP两种 timeoutSec 定义请求超时时间
	 * 单位秒 portalVer portal协议版本 目前有1.0和2.0
	 */
//	final static String basIp = config.getBas_ip();
//	final static String bas = config.getBas();
//	final static int basPort = Integer.parseInt(config.getBas_port());
//	final static String sharedSecret = config.getSharedSecret();
//	final static String authType = config.getAuthType();
//	final static int timeoutSec = Integer.parseInt(config.getTimeoutSec());
   static int portalVer = Integer.parseInt(config.getPortalVer());
	
	
	public static byte[] reqInfo(String Bas_IP, int bas_PORT,
			int timeout_Sec, byte[] SerialNo, byte[] UserIP, String sharedSecret) {
		DatagramSocket dataSocket = null;// 创建连接
		byte[] ErrorInfo = new byte[1];// 创建ErrorInfo包
		byte[] BBuff = new byte[16];
		byte[] Attrs = new byte[4];
		byte[] Req_Info;// 创建Req_Info包
		if(portalVer == 1){
			Req_Info = new byte[20];
			Req_Info[0] = (byte) 1;
		}else if(portalVer == 2){
			Req_Info = new byte[36];
			Req_Info[0] = (byte) 2;
		}else{
			if(config.getDebug().equals("1")){
				log.info("不支持该版本!!!");
			}
			
			ErrorInfo[0] = (byte) 12;
			return ErrorInfo;
		}
		
		Req_Info[1] = (byte) 9;
		Req_Info[2] = (byte) 0;
		Req_Info[3] = (byte) 0;
		Req_Info[4] = SerialNo[0];
		Req_Info[5] = SerialNo[1];
		Req_Info[6] = (byte) 0;
		Req_Info[7] = (byte) 0;
		Req_Info[8] = UserIP[0];
		Req_Info[9] = UserIP[1];
		Req_Info[10] = UserIP[2];
		Req_Info[11] = UserIP[3];
		Req_Info[12] = (byte) 0;
		Req_Info[13] = (byte) 0;
		Req_Info[14] = (byte) 0;
		Req_Info[15] = (byte) 1;
		for (int i = 0; i < 16; i++) {
			BBuff[i] = Req_Info[i];
		}
		Attrs[0] = (byte) 8;
		Attrs[1] = (byte) 4;
		Attrs[2] = (byte) 0;
		Attrs[3] = (byte) 0;
		Req_Info[16] = (byte) 8;
		Req_Info[17] = (byte) 4;
		Req_Info[18] = (byte) 0;
		Req_Info[19] = (byte) 0;
		if(portalVer == 2){
			byte[] Authen = Authenticator.MK_Authen(BBuff, Attrs, sharedSecret);
			for (int i = 0; i < 16; i++) {
				Req_Info[16 + i] = Authen[i];
			}
			Req_Info[32]= (byte) 8;
			Req_Info[33]= (byte) 4;
			Req_Info[34]= (byte) 0;
			Req_Info[35]= (byte) 0;
		}
		
		if(config.getDebug().equals("1")){
			log.info("REQ Info" + PortalUtil.Getbyte2HexString(Req_Info));
		}
		
		try {
			dataSocket = new DatagramSocket();
			DatagramPacket requestPacket = new DatagramPacket(Req_Info,
					Req_Info.length, InetAddress.getByName(Bas_IP), bas_PORT);// 创建发送数据包并发送给服务器
			dataSocket.send(requestPacket);
			byte[] ACK_Info_Data = new byte[50];// 接收服务器的数据包
			DatagramPacket receivePacket = new DatagramPacket(
					ACK_Info_Data, 50);
			dataSocket.setSoTimeout(timeout_Sec * 1000);// 设置请求超时3秒
			dataSocket.receive(receivePacket);
			if(config.getDebug().equals("1")){
				log.info("ACK Info"
						+ PortalUtil.Getbyte2HexString(ACK_Info_Data));
			}
			
			if ((int) (ACK_Info_Data[14] & 0xFF) == 0) {
				if(config.getDebug().equals("1")){
					log.info("建立INFO会话成功,准备发送REQ Challenge!!!");
				}
				
				return ACK_Info_Data;
			} else if ((int) (ACK_Info_Data[14] & 0xFF) == 1) {
				if(config.getDebug().equals("1")){
					log.info("建立INFO会话失败,不支持信息查询功能或者处理失败!!!");
				}
				
				ErrorInfo[0] = (byte) 11;
				return ErrorInfo;
			} else if ((int) (ACK_Info_Data[14] & 0xFF) == 2) {
				if(config.getDebug().equals("1")){
					log.info("建立INFO会话失败,消息处理失败，由于某种不可知原因，使处理失败，例如询问消息格式错误等!!!");
				}
				
				ErrorInfo[0] = (byte) 12;
				return ErrorInfo;
			} else {
				if(config.getDebug().equals("1")){
					log.info("建立INFO会话失败,出现未知错误!!!");
				}
				
				ErrorInfo[0] = (byte) 13;
				return ErrorInfo;
			}
		} catch (IOException e) {
			if(config.getDebug().equals("1")){
				log.info("建立INFO会话，请求无响应!!!");
			}
			
			ErrorInfo[0] = (byte) 01;
			return ErrorInfo;
		} finally {
			dataSocket.close();
		}
	}
}
